home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
198_01
/
display.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-21
|
38KB
|
1,561 lines
/*
* The functions in this file handle redisplay. There are two halves, the
* ones that update the virtual display screen, and the ones that make the
* physical display screen the same as the virtual display screen. These
* functions use hints that are left in the windows by the commands.
*
*/
#include <stdio.h>
#include "estruct.h"
#include "edef.h"
typedef struct VIDEOTAG {
int v_flag; /* Flags */
#if COLOR
int v_fcolor; /* current forground color */
int v_bcolor; /* current background color */
int v_rfcolor; /* requested forground color */
int v_rbcolor; /* requested background color */
#endif
char v_text[1]; /* Screen data. */
} VIDEO;
#define VFCHG 0x0001 /* Changed flag */
#define VFEXT 0x0002 /* extended (beyond column 80) */
#define VFREV 0x0004 /* reverse video status */
#define VFREQ 0x0008 /* reverse video request */
#define VFCOL 0x0010 /* color change requested */
#define VFSCROL 0x0020 /* cleared by scrolling */
#define WFSCROL 0x0040 /* window scrolled */
VIDEO **vscreen; /* Virtual screen. */
VIDEO **vsave; /* Used for scrolling. */
#if MEMMAP == 0
VIDEO **pscreen; /* Physical screen. */
VIDEO **psave; /* Used for scrolling. */
#endif
int didlins, didldel;
#define fastputc(c) TTputc(c)
/* these declarations must match termio.c */
#if VMS
extern char obuf[NOBUF]; /* Output buffer */
extern int nobuf; /* # of bytes in above */
#undef fastputc
#define fastputc(c) {if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = (c);}
#endif
#if V7 | USG | BSD
#undef fastputc
#define fastputc(c) putc((c), stdout)
#endif
#if (TERMCAP | VMSVT) & COLOR
extern int usedcolor;
#endif
/*
* Initialize the data structures used by the display code. The edge vectors
* used to access the screens are set up. The operating system's terminal I/O
* channel is set up. All the other things get initialized at compile time.
* The original window has "WFCHG" set, so that it will get completely
* redrawn on the first call to "update".
*/
vtinit()
{
register int i;
register VIDEO *vp;
char *malloc();
TTopen(); /* open the screen */
TTkopen(); /* open the keyboard */
TTrev(FALSE);
if (firstflag) {
vscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
vsave = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
}
if (vscreen == NULL || vsave == NULL)
exit(1);
#if MEMMAP == 0
if (firstflag) {
pscreen = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
psave = (VIDEO **) malloc(term.t_mrow*sizeof(VIDEO *));
}
if (pscreen == NULL || psave == NULL)
exit(1);
#endif
for (i = 0; i < term.t_mrow; ++i)
{
if (firstflag) vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
else vp = vscreen[i];
if (vp == NULL)
exit(1);
vp->v_flag = 0;
#if COLOR
vp->v_rfcolor = 7;
vp->v_rbcolor = 0;
#endif
vscreen[i] = vp;
#if MEMMAP == 0
if (firstflag) vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_mcol);
else vp = pscreen[i];
if (vp == NULL)
exit(1);
vp->v_flag = 0;
pscreen[i] = vp;
#endif
}
}
/*
* Clean up the virtual terminal system, in anticipation for a return to the
* operating system. Move down to the last line and clear it out (the next
* system prompt will be written in the line). Shut down the channel to the
* terminal.
*/
vttidy()
{
#if VMSVT | TERMCAP
ttscroll(0, term.t_nrow, 0);
#endif
mlerase();
movecursor(term.t_nrow, 0);
TTflush();
TTclose();
TTkclose();
}
/*
* Set the virtual cursor to the specified row and column on the virtual
* screen. There is no checking for nonsense values; this might be a good
* idea during the early stages.
*/
vtmove(row, col)
{
vtrow = row;
vtcol = col;
}
/* Write a character to the virtual screen. The virtual row and
column are updated. If we are not yet on left edge, don't print
it yet. If the line is too long put a "$" in the last column.
This routine only puts printing characters into the virtual
terminal buffers. Only column overflow is checked.
*/
vtputc(c)
int c;
{
register VIDEO *vp; /* ptr to line being updated */
vp = vscreen[vtrow];
if (c == '\t') {
do {
vtputc(' ');
} while (((vtcol + taboff) % tabsize) != 0);
} else if (vtcol >= term.t_ncol) {
++vtcol;
vp->v_text[term.t_ncol - 1] = '$';
} else if ((c&0x7F) < 0x20 || (c&0x7F) == 0x7F) {
vtputc('^');
vtputc((c&0x7F) ^ 0x40);
} else {
if (vtcol >= 0)
vp->v_text[vtcol] = c;
++vtcol;
}
}
/* Write a line to the virtual screen. Does equivalent of
for (j=0; j<llength(lp); ++j) vtputc(lgetc(lp, j));
*/
vtputl(lp)
register LINE *lp; /* line to update */
{
register VIDEO *vp; /* ptr to line being updated */
register int i, c;
vp = vscreen[vtrow];
for (i = 0; i < llength(lp); ++i) {
c = lgetc(lp, i);
if (c == '\t') {
do {
if (vtcol >= term.t_ncol) {
vp->v_text[term.t_ncol - 1] = '$';
return;
} else {
if (vtcol >= 0)
vp->v_text[vtcol] = ' ';
++vtcol;
}
} while (((vtcol + taboff) % tabsize) != 0);
} else if (vtcol >= term.t_ncol) {
vp->v_text[term.t_ncol - 1] = '$';
return;
} else if (c < 0x20 || c >= 0x7F) {
if ((c&0x7F) < 0x20 || (c&0x7F) == 0x7F) {
if (vtcol >= 0) vp->v_text[vtcol] = '^';
++vtcol;
if (vtcol >= term.t_ncol) {
vp->v_text[term.t_ncol - 1] = '$';
return;
} else if (vtcol >= 0)
vp->v_text[vtcol] = ((c&0x7F) ^ 0x40);
} else if (vtcol >= 0)
vp->v_text[vtcol] = c;
++vtcol;
} else {
if (vtcol >= 0)
vp->v_text[vtcol] = c;
++vtcol;
}
}
}
/* Write a string to the virtual screen and return its length */
int vtputs(s)
register char *s;
{
register VIDEO *vp; /* ptr to line being updated */
register int i;
vp = vscreen[vtrow];
for (i = 0; *s != '\0' && vtcol < term.t_ncol; ++i) {
if (vtcol >= 0) vp->v_text[vtcol] = *(s++);
++vtcol;
}
return(i);
}
/*
* Erase from the end of the software cursor to the end of the line on which
* the software cursor is located.
*/
vteeol()
{
register VIDEO *vp;
vp = vscreen[vtrow];
if (vtcol < 0) vtcol = 0;
while (vtcol < term.t_ncol)
vp->v_text[vtcol++] = ' ';
}
/* upscreen: user routine to force a screen update
always finishes complete update */
upscreen(f, n)
{
update(TRUE);
return(TRUE);
}
/*
* Make sure that the display is right. This is a three part process. First,
* scan through all of the windows looking for dirty ones. Check the framing,
* and refresh the screen. Second, make sure that "currow" and "curcol" are
* correct for the current window. Third, make the virtual and physical
* screens the same.
* force == HOOK like FALSE, but also does not update cursor
* (for edt page scrolling)
*/
update(force)
int force; /* force update past type ahead? */
{
register WINDOW *wp;
#if TYPEAH
if (force != TRUE && typahead())
return(TRUE);
#endif
#if VISMAC == 0
if (force != TRUE && kbdmode == PLAY)
return(TRUE);
#endif
/* update any windows that need refreshing */
wp = wheadp;
while (wp != NULL) {
if (wp->w_flag) {
/* if the window has changed, service it */
reframe(wp); /* check the framing */
if ((wp->w_flag & ~WFMODE) == WFEDIT)
updone(wp); /* update EDITed line */
else if ((wp->w_flag & ~(WFMODE | WFMOVE)) == WFSCROL)
updscroll(wp);
else if (wp->w_flag & ~WFMOVE)
updall(wp); /* update all lines */
if (wp->w_flag & WFMODE)
modeline(wp); /* update modeline */
wp->w_flag = 0;
wp->w_force = 0;
}
/* on to the next window */
wp = wp->w_wndp;
}
/* recalc the current hard